package com.iqiyi.pps.epg.core.service.channel;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iqiyi.kiwi.utils.HttpClientConnection;
import com.iqiyi.pps.epg.api.model.web.channel.*;
import com.iqiyi.pps.epg.api.model.web.query.TFilter;
import com.iqiyi.pps.epg.api.model.web.query.TPage;
import com.iqiyi.pps.epg.core.dao.base.Page;
import com.iqiyi.pps.epg.core.dao.base.PropertyFilter;
import com.iqiyi.pps.epg.core.dao.channel.*;
import com.iqiyi.pps.epg.core.model.channel.*;
import com.iqiyi.pps.epg.core.rpc.qipu.Composite.AlternatePlayCollectionImpl;
import com.iqiyi.pps.epg.core.rpc.qipu.QipuService;
import com.iqiyi.pps.epg.core.service.broadcast.BroadcastControlService;
import com.iqiyi.pps.epg.core.service.carousel.CarouselService;
import com.iqiyi.pps.epg.core.service.program.ISnapAsyncService;
import com.iqiyi.pps.epg.core.service.program.ProgramService;
import com.iqiyi.pps.epg.core.service.reservation.ReservationService;
import com.iqiyi.pps.epg.core.service.stream.LiveChannelStreamService;
import com.iqiyi.pps.epg.core.utils.*;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.type.IntegerType;
import org.hibernate.type.LongType;
import org.hibernate.type.StringType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class ChannelServiceImpl implements ChannelService {
    public static Logger logger = LoggerFactory.getLogger(ChannelServiceImpl.class);
    @Autowired
    private ChannelBaseDao channelBaseDao;
    @Autowired
    private ChannelBossDao channelBossDao;
    @Autowired
    private ChannelTagDao channelTagDao;

    @Autowired
    private ChannelConfigDao channelConfigDao;
    @Autowired
    private QipuService qipuService;
    @Autowired
    private ChannelLogDao channelLogDao;
    @Autowired
    private ChannelCodeDao channelCodeDao;
    @Autowired
    private ReservationService reservationService;
    @Autowired
    private CarouselService carouselService;

    @Autowired
    private LiveChannelStreamService liveChannelStreamService;
    @Autowired
    private BroadcastControlService broadcastControlService;
    @Autowired
    private ProgramService programService;
    @Autowired
    private ChannelSearchConfigDao channelSearchConfigDao;

    @Autowired
    private ISnapAsyncService snapAsyncService;

    @Override
    public void saveBase(ChannelBase entity) {
        if (entity.getQipuId() <= 0) {
            List<Long> qipuIdList = qipuService.registerQipuId(22, 1);
            entity.setQipuId(qipuIdList.get(0));
        }
//        if (entity.getOldQipuId() <= 0) {
//            List<Long> oldQipuIdList = qipuService.registerQipuId(18, 1);
//            entity.setOldQipuId(oldQipuIdList.get(0));
//        }
        entity.setOldQipuId(0L);

        if (entity.getLogoEntityId() <= 0) {
            List<Long> qipuIdList = qipuService.registerQipuId(04, 1);
            entity.setLogoEntityId(qipuIdList.get(0));
        }
        String pageUrl = UrlGeneratorUtil.generateUrl(entity.getQipuId());
        pageUrl = "http://www.iqiyi.com/c_" + pageUrl + ".html";
        entity.setPageUrl(pageUrl);
        channelBaseDao.save(entity);
        //奇谱基本信息
        //暂时取消同步
        /*
        qipuService.setLiveChannelBaseToQipu(entity.getQipuId(), entity);

        qipuService.setIsEnableToQipu(entity.getQipuId(), entity.getIsEnable() > 0 ? true : false);
        qipuService.setQitanToQipu(entity);
        qipuService.setChannelPageUrlToQipu(entity.getQipuId(), pageUrl);
        //写老奇谱
        qipuService.addTvChannelToQipu(entity.getOldQipuId(), entity);
        if (entity.getDefaultLogoUrl() != null) {
            qipuService.setChannelLogoToQipu(entity.getQipuId(), entity.getDefaultLogoUrl());
            qipuService.addTvChannelToQipu(entity.getOldQipuId(), entity);
            qipuService.setImageDataToQipu(entity);
        }
        */
    }

    @Override
    public void saveBoss(ChannelBoss entity) {
        channelBossDao.save(entity);
        /*
        qipuService.setLiveChannelBossToQipu(channelBaseDao.get(entity.getFatherId()).getQipuId(), entity);
        qipuService.setLiveChannelBossToQipu(channelBaseDao.get(entity.getFatherId()).getOldQipuId(), entity);
        */
    }

    @Override
    public void saveTag(ChannelTag entity) {
        channelTagDao.save(entity);
        /*
        qipuService.addTagToQipu(channelBaseDao.get(entity.getFatherId()).getQipuId(), entity);
        qipuService.addTagToQipu(channelBaseDao.get(entity.getFatherId()).getOldQipuId(), entity);
        */
    }

    @Override
    public void saveLog(ChannelLog entity) {
        channelLogDao.save(entity);
    }

    @Override
    public void deleteTag(ChannelTag entity) {
        channelTagDao.delete(entity);
    }

    @Override
    public void updateChannelSync(long id, int isSync) {
        ChannelBase channelBase = channelBaseDao.get(id);
        if (channelBase != null) {
            channelBase.setIsSync(isSync);
            channelBaseDao.save(channelBase);
        }
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public ChannelBase getChannelBase(long id) {
        return channelBaseDao.get(id);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public ChannelBase getChannelByQipuId(long qipuId) {
        return channelBaseDao.findUniqueBy("qipuId", qipuId);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public ChannelBase carouselTableNo(Integer carouselTableNo, int type, String channelId) {
        List<PropertyFilter> filters = new ArrayList<PropertyFilter>();
        if (null != channelId) {
            filters.add(new PropertyFilter("NEQL_id", channelId));
        }
        filters.add(new PropertyFilter("EQI_carouselTableNo", carouselTableNo + ""));
        filters.add(new PropertyFilter("EQI_type", type + ""));
        filters.add(new PropertyFilter("NEQI_isEnable", "-1"));
        List<ChannelBase> list = channelBaseDao.find(filters);
        if (list.size() == 0) {
            return null;
        }
        return list.get(list.size() - 1);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public ChannelBoss getChannelBoss(long fatherId) {
        return channelBossDao.findUniqueBy("fatherId", fatherId);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<ChannelTag> getChannelTag(long fatherId) {
        return channelTagDao.findBy("fatherId", fatherId);
    }

    /**
     * 设置过播控时更新base表里的has_broadcast ＝ 1
     *
     * @param channelId
     * @return
     */
    public boolean hasBroadcast(long channelId) {
        ChannelBase entity = getChannelBase(channelId);
        if (entity != null && entity.getHasBroadcast() != ChannelBase.HAS_BROADCAST) {
            entity.setHasBroadcast(ChannelBase.HAS_BROADCAST);
            saveBase(entity);
        }
        return true;
    }

    /**
     * 设置过播控时更新base表里的has_broadcast ＝ 1
     *
     * @param entity
     * @return
     */
    public boolean hasBroadcast(ChannelBase entity) {
        if (entity != null && entity.getHasBroadcast() != ChannelBase.HAS_BROADCAST) {
            entity.setHasBroadcast(ChannelBase.HAS_BROADCAST);
            saveBase(entity);
        }
        return true;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public TChannelPage getChanneList(TPage page, TFilter filter) {
        TChannelPage data = new TChannelPage();

        try {
            long startTime = System.currentTimeMillis();
            String countSql = "SELECT COUNT(*) AS total " +
                    "FROM channel_base base LEFT JOIN channel_boss boss ON base.id = boss.father_id WHERE 1 ";
            String listSql = "SELECT base.*, boss.* " +
                    "FROM channel_base base LEFT JOIN channel_boss boss ON base.id = boss.father_id WHERE 1 ";
            String sql = "";

            if (filter.getFilters().containsKey("liveType")) {
                sql += " AND base.live_type = " + filter.getFilters().get("liveType");
            }
            if (filter.getFilters().containsKey("type")) {
                sql += " AND base.type = " + filter.getFilters().get("type");
            }
            if (filter.getFilters().containsKey("qipuId")) {
                sql += " AND ( base.qipu_id = " + filter.getFilters().get("qipuId") + " OR  base.old_qipu_id = " + filter.getFilters().get("qipuId") + ") ";
            }
            if (filter.getFilters().containsKey("isEnable")) {
                sql += " AND base.is_enable = " + filter.getFilters().get("isEnable");
            }
            if (filter.getFilters().containsKey("isDelete")) {
                String isDelete = filter.getFilters().get("isDelete");
                if ("0".equals(isDelete)) {
                    sql += " AND base.is_enable != -1";
                } else if ("1".equals(isDelete)) {
                    sql += " AND base.is_enable = -1";
                }
            }
            if (filter.getFilters().containsKey("startDate")) {
                sql += " AND base.add_time >= '" + filter.getFilters().get("startDate") + "'";
            }
            if (filter.getFilters().containsKey("endDate")) {
                sql += " AND base.add_time <= '" + filter.getFilters().get("endDate") + "'";
            }
//            if (filter.getFilters().containsKey("isMemeberFree")) {
//                sql += " AND boss.is_memeber_free = " + filter.getFilters().get("isMemeberFree");
//            }
            if (filter.getFilters().containsKey("name")) {
                sql += " AND base.name LIKE '%" + StringEscapeUtils.escapeSql(filter.getFilters().get("name")) + "%'";
            }
//            if (filter.getFilters().containsKey("universalCode")) {
//                sql += " AND base.universal_code LIKE '%" + filter.getFilters().get("universalCode") + "%'";
//            }
//            if (filter.getFilters().containsKey("operator")) {
//                sql += " AND base.operator LIKE '%" + filter.getFilters().get("operator") + "%'";
//            }
//            if (filter.getFilters().containsKey("elementId")) {
//                sql += " AND base.id =" + filter.getFilters().get("elementId") + " ";
//            }
            String totalCount = channelBaseDao.getSession().createSQLQuery(countSql + sql).addScalar("total", new StringType()).list().get(0).toString();

            sql += "  ORDER BY base.id DESC LIMIT " + (page.getPageNo() - 1) * page.getPageSize() + " , " + page.getPageSize();
            List result = channelBaseDao.getSession().createSQLQuery(listSql + sql)
                    .addEntity("base", ChannelBase.class)
                    .addEntity("boss", ChannelBoss.class)
                    .list();
            List<TChannel> channelList = new ArrayList();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // String s = "{\"control\":0,\"program\":1,\"stream\":0}";
            for (Object single : result) {
                TChannel tChannel = new TChannel();
                Object[] obj = (Object[]) single;
                ChannelBase channelBase = (ChannelBase) obj[0];
                ChannelBoss channelBoss = (ChannelBoss) obj[1];

                long ctime = System.currentTimeMillis();
                List<ChannelTag> channelTags = getChannelTag(channelBase.getId());
                logger.info("getChannelTag(fatherId): {}", System.currentTimeMillis() - ctime);
                tChannel.setId(channelBase.getId());
                tChannel.setOldQipuId(channelBase.getOldQipuId());
                tChannel.setQipuId(channelBase.getQipuId());
                tChannel.setName(channelBase.getName());
                tChannel.setOperator(channelBase.getOperator());
                tChannel.setShortName(channelBase.getShortName());
                tChannel.setUniversalCode(channelBase.getUniversalCode());
                tChannel.setDescription(channelBase.getDescription());
                tChannel.setPassportId(channelBase.getPassportId());
                tChannel.setPpsBaikeId(channelBase.getPpsBaikeId());
                tChannel.setLiveType(channelBase.getLiveType());
                tChannel.setType(channelBase.getType());
                tChannel.setLocation(channelBase.getLocation());
                tChannel.setPageUrl(channelBase.getPageUrl());
                tChannel.setLogoUrl(channelBase.getLogoUrl());
                tChannel.setDefaultLogoUrl(channelBase.getDefaultLogoUrl());
                tChannel.setLogoEntityId(channelBase.getLogoEntityId());
                tChannel.setMaxPlaybackPeriod(channelBase.getMaxPlaybackPeriod());
                tChannel.setTempName(channelBase.getTempName());
                tChannel.setTempStartTime(sdf.format(channelBase.getTempStartTime()));
                tChannel.setTempEndTime(sdf.format(channelBase.getTempEndTime()));
                tChannel.setQitanId(channelBase.getQitanId());
                tChannel.setOrderBy(channelBase.getOrderBy());
                tChannel.setIsEnable(channelBase.getIsEnable());
                tChannel.setIsSync(channelBase.getIsSync());
                tChannel.setStatus(channelBoss.getStatus());
                tChannel.setAddTime(sdf.format(channelBase.getAddTime()));
                tChannel.setUpdateTime(sdf.format(channelBase.getUpdateTime()));
                tChannel.setIsMemeberFree(channelBoss.getIsMemeberFree() == null ? 0 : channelBoss.getIsMemeberFree());
                tChannel.setPaidStartTime(sdf.format(channelBoss.getPaidStartTime()));
                tChannel.setPaidEndTime(sdf.format(channelBoss.getPaidEndTime()));
                tChannel.setInterruptHintType(channelBase.getInterruptHintType());
                tChannel.setAlternatePlayCollection(channelBase.getAlternatePlayCollection());
                tChannel.setCarouselTableNo(channelBase.getCarouselTableNo());
                if (channelBase.getPanoFormat() != null) {
                    tChannel.setPanoFormat(channelBase.getPanoFormat());
                }
                //tChannel.setMenuShow(menuShow(channelBase.getId()));
                tChannel.setMenuShow("{\"control\":" + channelBase.getHasBroadcast() + ",\"program\":" + channelBase.getHasPrograms() + ",\"stream\":" + channelBase.getHasStream() + "}");
                if (channelTags.size() > 0) {
                    StringBuilder sb = new StringBuilder();
                    for (ChannelTag item : channelTags) {
                        sb.append(item.getTag1()).append("_").append(item.getTag2()).append(",");
                    }
                    tChannel.setTag(sb.substring(0, sb.length() - 1));
                }
                channelList.add(tChannel);
            }
            data.setResult(channelList);
            page.setTotalCount(Long.valueOf(totalCount));
            data.setTPage(page);

            logger.info("ChannelServiceImpl.getChanneList(page, filter): {}", System.currentTimeMillis() - startTime);
        } catch (Exception e) {
            logger.error("[ChannelServiceImpl][getChanneList][exception=]", e);
        }
        return data;
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public String menuShow(long fatherId) {
        Map<String, Integer> ret = new HashMap<>();

        long startTime = System.currentTimeMillis();
        int streamSize = (int) liveChannelStreamService.count(fatherId);
        logger.info("liveChannelStreamService.count(fatherId): {}", System.currentTimeMillis() - startTime);
        ret.put("stream", streamSize);

        startTime = System.currentTimeMillis();
        boolean hasPrograms = programService.hasPrograms(fatherId);
        logger.info("programService.hasPrograms(fatherId): {}", System.currentTimeMillis() - startTime);
        ret.put("program", hasPrograms ? 1 : 0);

        startTime = System.currentTimeMillis();
        boolean isSet = broadcastControlService.isSetBroadcastControl(fatherId);
        logger.info("broadcastControlService.isSetBroadcastControl(fatherId): {}", System.currentTimeMillis() - startTime);
        ret.put("control", isSet ? 1 : 0);

        return JSON.toJSONString(ret);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<ChannelBase> getChannelBaseList() {
        Criteria crit = channelBaseDao.createCriteria();
        return channelBaseDao.find(crit);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<ChannelBase> findChannelBaseList(List<Criterion> cList) {
        if (cList == null) {
            return null;
        }
        Criteria crit = channelBaseDao.createCriteria();
        for (Criterion criterion : cList) {
            crit.add(criterion);
        }
        return channelBaseDao.find(crit);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<ChannelLog> findChannelLogList(List<Criterion> cList, int maxResult, Order order) {
        if (cList == null) {
            return null;
        }
        Criteria crit = channelLogDao.createCriteria();
        for (Criterion criterion : cList) {
            crit.add(criterion);
        }
        if (maxResult != -1) {
            crit.setMaxResults(maxResult);
        }
        crit.addOrder(order);
        return channelLogDao.find(crit);
    }


    @Override
    public List<ChannelBase> getChannelBaseList(Integer isSync) {
        return channelBaseDao.findBy("isSync", isSync);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<String> getChannelBaseCodeList() {
        String hql = "select distinct universalCode from ChannelBase where (isEnable = 1 or isEnable = 0) and liveType = 1 and LENGTH(universalCode) > 0 ";
        List<String> resultList = channelBaseDao.getSession().createQuery(hql).list();
        return resultList;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<ChannelConfig> getConfig(String type) {
        Criteria criteria = channelConfigDao.createCriteria();
        criteria.add(Restrictions.eq("type", type));
        criteria.add(Restrictions.eq("status", ChannelConfig.STATUS_SHOW));
        return channelConfigDao.find(criteria);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public ChannelConfig getConfigData(String type, int key) {

        Criteria criteria = channelConfigDao.createCriteria();
        criteria.add(Restrictions.eq("type", type));
        criteria.add(Restrictions.eq("key", key));
        criteria.add(Restrictions.eq("status", ChannelConfig.STATUS_SHOW));
        return channelConfigDao.findUnique(criteria);

    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public String getTagName(Long fatherId, Long id) {
        String name = "";
        String url = "http://xinqi.if.iqiyi.com/basic/categories.json?father_id=" + fatherId;
        for (int i = 0; i < 3; i++) {
            HttpClientConnection hcc = new HttpClientConnection(url, HttpClientConnection.GET_METHOD);

            hcc.connect();

            if (hcc.getStatus() == 200) {
                JSONArray result = JSONArray.parseArray(hcc.getBody());
                for (int j = 0; j < result.size(); j++) {
                    JSONObject temp = (JSONObject) result.get(j);
                    if (temp.getLongValue("id") == id) {
                        name = temp.getString("name");
                        break;
                    }
                }
                break;
            }
        }
        return name;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Long getQipuId(Long id) {
        return getChannelBase(id).getQipuId();
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Long getOldQipuId(Long id) {
        return getChannelBase(id).getOldQipuId();
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public boolean checkName(Long fatherId, String name) {
        Criteria criteria = channelBaseDao.createCriteria();
        if (fatherId > 0) {
            criteria.add(Restrictions.ne("id", fatherId));
        }
        criteria.add(Restrictions.ne("isEnable", -1));
        criteria.add(Restrictions.eq("name", name));
        List<ChannelBase> list = channelBaseDao.find(criteria);
        return list.size() > 0 ? false : true;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public boolean checkUniversalCode(Long fatherId, String universalCode) {
        Criteria criteria = channelBaseDao.createCriteria();
        if (fatherId > 0) {
            criteria.add(Restrictions.ne("id", fatherId));
        }
        criteria.add(Restrictions.ne("isEnable", -1));
        criteria.add(Restrictions.eq("universalCode", universalCode));
        List<ChannelBase> list = channelBaseDao.find(criteria);
        return list.size() > 0 ? false : true;
    }

    @Override
    public boolean delChannel(Long id) {
        boolean ret = false;
        ChannelBase channelBase = channelBaseDao.get(id);
        if (channelBase != null) {
            channelBase.setIsEnable(-1);
            channelBase.setIsSync(1);

            String alternatePlayCollection = channelBase.getAlternatePlayCollection();
            channelBase.setAlternatePlayCollection("");
            channelBaseDao.save(channelBase);

            reservationService.delByChannelId(id);
            carouselService.delByChannelId(id);
            carouselService.delAutomationByChannelId(id);
            qipuService.setObjectDeletedToQipu(channelBase.getQipuId(), true);
            if (channelBase.getLiveType() == ChannelBase.LIVE_TYPE_LS) {
                snapAsyncService.interruptTaskByChannel(channelBase.getId());
            }
            //qipuService.setObjectDeletedToQipu(channelBase.getOldQipuId(), true);

            List<Long> beibokuQipuIds = AlternatePlayCollectionImpl.getQipuIds(alternatePlayCollection);
            boolean beiboFlag = ApiBeibokuUtil.deleteBeiboku(
                    id, beibokuQipuIds);
            logger.info("[ChannelServiceImpl][delChannel][channelId={}][delete beiboku] {}",
                    id, beiboFlag ? "success" : "failed");

            writeChannelLog(channelBase.getId(), Constants.LogType.CHANNEL_BEIBOKU_DELETE.getIndex(),
                    "删除备播库[channelIds=" + channelBase.getId() + "][qipuIds=" + beibokuQipuIds.toString() + "] " + (beiboFlag ? "success" : "failed"));


            ret = true;
        }
        return ret;

    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<ChannelLog> getChannelLogList(long fatherId) {
        Criteria criteria = channelLogDao.createCriteria();
        criteria.add(Restrictions.eq("fatherId", fatherId));
        criteria.addOrder(Order.desc("id"));
        criteria.setMaxResults(100);
        return channelLogDao.find(criteria);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public TChannelLogPage getChannelLogList(TPage page, TFilter filter) {
        List<PropertyFilter> filterList = TransUtil.builderFilterList(filter);
        Page<ChannelLog> dbPage = TransUtil.buildPage(page);
        Page<ChannelLog> pageData = channelLogDao.findPage(dbPage, filterList);
        List<ChannelLog> dataList = pageData.getResult();
        TChannelLogPage carouselPage = new TChannelLogPage();
        page.setTotalCount(pageData.getTotalCount());
        carouselPage.setTPage(page);
        List<TChannelLog> tCarouselList = transToTChannelLogList(dataList);
        carouselPage.setResult(tCarouselList);
        return carouselPage;
    }

    private List<TChannelLog> transToTChannelLogList(List<ChannelLog> dataList) {
        List<TChannelLog> resultList = new ArrayList<>();
        TChannelLog tChannelLog = null;
        for (ChannelLog tempData : dataList) {
            tChannelLog = transToTChannelLog(tempData);
            resultList.add(tChannelLog);
        }
        return resultList;
    }

    private TChannelLog transToTChannelLog(ChannelLog tempData) {
        TChannelLog _TChannelLog = new TChannelLog();
        _TChannelLog.setId(tempData.getId());
        _TChannelLog.setFatherId(tempData.getFatherId());
        _TChannelLog.setUser(tempData.getUser());
        _TChannelLog.setType(tempData.getType());
        _TChannelLog.setDescr(tempData.getDescr());
        _TChannelLog.setAddTime(DateTimeUtil.transLongFormat(tempData.getAddTime().getTime()));
        return _TChannelLog;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<ChannelCode> getChannelCodeList(String key) {
        String sql = "select * from tvmao_channel_code ";
        if (key != null && StringUtils.isNotBlank(key)) {
            key = StringEscapeUtils.escapeSql(key);
            sql += " where code like '%" + key + "%' or name like '%" + key + "%'";
        }
        List<ChannelCode> resultList = channelCodeDao.getSession().createSQLQuery(sql).addEntity(ChannelCode.class).list();
        return resultList;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<ChannelLog> getChannelLogUser(long fatherId) {
        String sql = "select * from channel_log where father_id='" + fatherId + "' and type like '60%' " +
                " and user not in ('system', '_system_', '0') group by user";

        List<ChannelLog> resultList = channelLogDao.getSession().createSQLQuery(sql).addEntity(ChannelLog.class).list();
        return resultList;
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<Long> fetchChannelList(String minTime, String maxTime) {
        String sql = "select channel.id channelId ,count(program.id) programNum from channel_base channel , live_episode program " +
                " where program.father_id = channel.id and channel.is_enable = 1 and channel.live_type = 2 " +
                " and program.start_play_time >='" + minTime + "' and program.start_play_time <='" + maxTime + "' group by program.father_id";
        List<Object[]> result = channelBaseDao.getSession().createSQLQuery(sql).addScalar("channelId", new LongType()).addScalar("programNum", new IntegerType()).list();
        List<Long> channelIdList = new ArrayList<Long>();
        for (Object[] single : result) {
            channelIdList.add((Long) single[0]);
        }
        return channelIdList;
    }

    @Override
    public void notifyHasPrograms(long channelId) {
        ChannelBase channelBase = getChannelBase(channelId);
        channelBase.setEpisodeUpdateTime(new Timestamp(System.currentTimeMillis()));
        if (channelBase.getHasPrograms() == null || channelBase.getHasPrograms() == ChannelBase.NO_PROGRAMS) {
            channelBase.setHasPrograms(ChannelBase.HAS_PROGRAMS);
        }
        channelBase.setIsSync(1);
        saveBase(channelBase);
    }

    @Override
    public List<ChannelLog> getStreamErrorLogUser(long fatherId) {
        String sql = "select * from channel_log where father_id='" + fatherId + "' and " +
                "(type between '100' and '102' or type between '300' and '307' or type between '600' and '602')" +
                " and user not in ('system', '_system_', '0') group by user";
        List<ChannelLog> resultList = channelLogDao.getSession().createSQLQuery(sql).addEntity(ChannelLog.class).list();
        return resultList;
    }

    public SearchSettingConfig getSearchConfig(long fatherId) {
        List<SearchSettingConfig> configList = channelSearchConfigDao.findBy("id", fatherId);
        if (configList.size() > 0) {
            return configList.get(0);
        }
        return null;
    }

    public void saveSearchConfig(SearchSettingConfig dataConfig) {
        channelSearchConfigDao.save(dataConfig);
    }

    private static String[] SYSTEM_USRS = {"system", "_system_", "0"};

    @Transactional
    public List<String> searchForLogUser(long channelId) {
        Criteria criteria = channelLogDao.createCriteria();
        criteria.add(Restrictions.eq("fatherId", channelId));
        long maxTime = System.currentTimeMillis();
        long minTime = System.currentTimeMillis() - 90 * DateTimeUtil.DAY_TIME;
        criteria.add(Restrictions.between("addTime", new Timestamp(minTime), new Timestamp(maxTime)));
        criteria.add(Restrictions.not(Restrictions.in("user", SYSTEM_USRS)));
        criteria.setProjection(Projections.groupProperty("user"));
        return criteria.list();
    }


    @Transactional
    public List<String> searchForUser(String configKey) {
        List<ChannelConfig> list = getConfig(configKey);
        List<String> retList = new ArrayList<String>();
        for (ChannelConfig config : list) {
            retList.add(config.getVal());
        }
        return retList;
    }

    @Transactional
    public void sqlNotifyHasStream(long channelId) {
        String hql = "update ChannelBase set hasStream = 1 , isSync = 1 where id =" + channelId;
        int executeNum = channelBaseDao.createQuery(hql).executeUpdate();
        logger.info("[sqlNotifyHasStream] channelId={},executeNum={}", channelId, executeNum);
    }


    public List<ChannelBase> suggestChannelInfo(long channelQipuId, String channelName, int liveType) {
        StringBuffer sqlBuffer = new StringBuffer();
        String hsql = "select * from channel_base where is_enable = 1 and name like '%" + channelName + "%'";
        if (channelQipuId > 0) {
            hsql = hsql + " and qipu_id = " + channelQipuId;
        }

        if (liveType > 0) {
            hsql = hsql + " and live_type = " + liveType;
        }

        hsql = hsql + " limit 10 ";

        sqlBuffer.append(hsql);

        List<ChannelBase> resultList = channelBaseDao.getSession().createSQLQuery(sqlBuffer.toString()).addEntity(ChannelBase.class).list();
        return resultList;
    }

    public List<String> searchForStreamErrorLogUser(long channelId) {
        List<ChannelLog> list = getStreamErrorLogUser(channelId);
        List<String> retList = new ArrayList<String>();
        for (ChannelLog channelLog : list) {
            retList.add(channelLog.getUser());
        }
        return retList;
    }

    public List<String> searchForCarouselLogUser(long channelId) {
        List<ChannelLog> list = getCarouselLogUser(channelId);
        List<String> retList = new ArrayList<String>();
        for (ChannelLog channelLog : list) {
            retList.add(channelLog.getUser());
        }
        return retList;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<ChannelLog> getCarouselLogUser(long fatherId) {
        String sql = "select * from channel_log where father_id='" + fatherId + "' and type like '60%' " +
                " and user not in ('system', '_system_', '0') group by user";

        List<ChannelLog> resultList = channelLogDao.getSession().createSQLQuery(sql).addEntity(ChannelLog.class).list();
        return resultList;
    }

    private void writeChannelLog(long channelId, int type, String descr) {
        try {
            ChannelLog tChannelLog = new ChannelLog();
            tChannelLog.setFatherId(channelId);
            tChannelLog.setType(type);

            tChannelLog.setUser("system");
            tChannelLog.setDescr(descr);
            saveLog(tChannelLog);
        } catch (Exception e) {
            logger.info("[ChannelServiceImpl][writeChannelLog][exception=][channelId={}][type={}][desc={}]", e, channelId, type, descr);
        }
    }

    @Override
    public TChannelPcaPage findChannelByCategoryId(String categoryId, String channelId, String channelName, TPage page) {
        logger.info("[ChannelServiceImpl][findChannelByCategoryId][categoryId={}][channelId={}][channelName={}]", categoryId, channelId, channelName);
        TChannelPcaPage tChannelPcaPage = new TChannelPcaPage();
        List<TChannelPca> tChannelPcas = new ArrayList<TChannelPca>();
        try {
            String tempPattern = "${PARAMS}";
            String totalPattern = "select COUNT(*)";
            String paramPattern = "select base.qipu_id channelId, base.name channelName, base.live_type liveType, base.type type";

            StringBuffer sql = new StringBuffer();
            sql.append(tempPattern).append(" from channel_base base, channel_tag tag");
            sql.append(" where base.id = tag.father_id and base.is_enable = 1");
            //sql.append("select base.qipu_id channelId, base.name channelName, base.live_type liveType, base.type type from channel_base base, channel_tag tag where base.id = tag.father_id and base.is_enable = 1 and base.formal = 1");
            sql.append(" and ((tag.tag1 = " + categoryId + " and tag.tag2 = 0) or tag.tag2 = " + categoryId + ")");
            if (StringUtils.isNotEmpty(channelId)) {
                sql.append(" and base.qipu_id = " + channelId);
            }
            if (StringUtils.isNotEmpty(channelName)) {
                sql.append(" and base.name like '%" + channelName + "%'");
            }
            sql.append(" order by base.add_time desc");

            Page<TChannelPca> dbPage = TransUtil.buildPage(page);

            if (dbPage.isAutoCount()) {
                String totalCount = channelBaseDao.getSession().createSQLQuery(sql.toString().replace(tempPattern, totalPattern)).uniqueResult().toString();
                page.setTotalCount(Long.valueOf(totalCount));
            }
            sql.append(" limit ").append((dbPage.getPageNo() - 1) * dbPage.getPageSize()).append(",").append(dbPage.getPageSize());

            List<Object[]> result = channelBaseDao.getSession().createSQLQuery(sql.toString().replace(tempPattern, paramPattern))
                    .addScalar("channelId", new LongType())
                    .addScalar("channelName", new StringType())
                    .addScalar("liveType", new IntegerType())
                    .addScalar("type", new IntegerType())
                    .list();

            for (Object[] objects : result) {
                TChannelPca tChannelPca = new TChannelPca();
                tChannelPca.setChannelId((Long) objects[0]);
                tChannelPca.setChannelName((String) objects[1]);
                tChannelPca.setLiveType(ChannelBase.LIVE_TYPE_MAP.get(objects[2]));
                tChannelPca.setType(ChannelBase.TYPE_MAP.get(objects[3]));
                tChannelPcas.add(tChannelPca);
            }

            tChannelPcaPage.setTPage(page);
            tChannelPcaPage.setResult(tChannelPcas);
            logger.info("[ChannelServiceImpl][findChannelByCategoryId][categoryId={}][result={}]", categoryId, JSON.toJSONString(tChannelPcaPage));
        } catch (Exception e) {
            logger.error("[ChannelServiceImpl][findChannelByCategoryId][error]", e);
        }
        return tChannelPcaPage;
    }

    @Override
    public int saveConfig(ChannelConfig entity) {
        channelConfigDao.saveOnly(entity);
        return entity.getId();
    }

    @Override
    public void editConfig(ChannelConfig entity) {
        channelConfigDao.save(entity);
    }

    @Override
    public List<ChannelConfig> getAllConfigs() {
        Criteria criteria = channelConfigDao.createCriteria();
        return channelConfigDao.find(criteria);
    }

    @Override
    public List<TChannelConfig> transTConfigs(List<ChannelConfig> list) {
        List<TChannelConfig> newList = new ArrayList<>();
        TChannelConfig temp = null;
        for (ChannelConfig channelConfig : list) {
            temp = new TChannelConfig();
            temp.setId(channelConfig.getId());
            temp.setKey(channelConfig.getKey());
            temp.setVal(channelConfig.getVal());
            temp.setDesc(channelConfig.getDescr());
            temp.setType(channelConfig.getType());
            temp.setStatus(channelConfig.getStatus());
            newList.add(temp);
        }
        return newList;
    }

    @Override
    public boolean hasConfig(String type, int key) {
        Criteria criteria = channelConfigDao.createCriteria();
        criteria.add(Restrictions.eq("type", type));
        criteria.add(Restrictions.eq("key", key));
        List<ChannelConfig> list = channelConfigDao.find(criteria);
        return list.size() >= 1;
    }


    @Override
    public List<ChannelConfig> findChannelConfigList(List<Criterion> criterionList, List<Order> orderList) {
        Criteria criteria = channelConfigDao.createCriteria();
        if (criterionList != null) {
            for (Criterion temp : criterionList) {
                criteria.add(temp);
            }
        }
        if (orderList != null) {
            for (Order temp : orderList) {
                criteria.addOrder(temp);
            }
        }
        return channelConfigDao.find(criteria);
    }

    public int updateDefaultLogoUrl(long channelId, String url) {
        String hql = "update ChannelBase set defaultLogoUrl = ? , isSync = 1 where id =" + channelId;
        int executeNum = channelBaseDao.createQuery(hql).setString(0, url).executeUpdate();
        logger.info("channelId={},executeNum={},defaultLogoUrl={}", channelId, executeNum, url);
        return executeNum;
    }
}
